%% Read and Solve Models with Optimal Policy
%
% Load the model file `optimal_policy.model` and create three different
% versions of it: a model with a simple policy rule, an optimal
% discretionary (time-consistent) policy model, and an optimal commitment
% policy model. Calibrate, solve and save the model objects for further
% use.

%% Clear Workspace
%
% Clear workspace, close all graphics figures, clear command window, and
% check the IRIS version.

clear;
close all;
home;
irisrequired 20140319;
%#ok<*NOPTS>
 
%% Load Three Versions of the Model
%
% Create a parameter database upfront <?paramDbase?>, before loading the
% model file. The same parameter database will be reused in all versions of
% the model <?reuseP?>.
%
% Load the model file three times, using different combinations of the
% switch `optimal_policy` <?switch?> (a user-defined switch used in the
% model file to distinguish a model with a simple rule versus models with
% optimal policy defined by a loss function), and the option `'optimal='`
% <?optimalOption?>, which controls the type of optimal policy calculated
% by IRIS.
%
% # Set `'optimal_policy=' false` to load the model file with a simple
% inflation-targeting rule;
% # Set `optimal_policy=' true` to load the model file with a loss
% function, and set `'optimal=' 'discretion'` telling IRIS to calculate
% equations that describe discretionary optimal policy. Under discretion,
% the expectations (leads of variables) are taken as given, and not
% differentiated with respect to.
% # Set `optimal_policy=' true` to load the model file with a loss
% function, and set `'optimal=' 'commitment'` telling IRIS to calculate
% equations that describe optimal commitment policy. Under commitment, the
% expectations (leads of variables) used by the policymaker to optimize the
% loss function.

P = struct(); %?paramDbase?
P.del1 = 0.7; 0.5;
P.del2 = 0.1;
P.sgm = 0.05;
P.alp = 0.65; 0.5;
P.gam = 0.1;
P.bet = 0.9; 0.99;
P.lmb1 = 0.1;
P.lmb2 = 0.1;
P.rho = 0.8;
P.mu = 5;
P.targ = 2;

P

m1 = model('optimal_policy.model', ...
    'linear=',true,'assign=',P, ... %reuseP?
    'optimal_policy=',false); %?switch?

%%

m2 = model('optimal_policy.model', ...
    'linear=',true,'assign=',P, ... %?reuseP?
    'optimal_policy=',true, ... %?switch?
    'optimal=','discretion'); %?optimalOptions?

%%

m3 = model('optimal_policy.model', ...
    'linear=',true,'assign=',P, ... %?reuseP?
    'optimal_policy=',true, ... %?switch?
    'optimal=','commitment'); %?optimalOption?

%% Show Newly Created Equations
%
% In model objects `m2` and `m3`, IRIS calculates the equations
% corresponding to the derivatives of the Lagrangian (i.e. the loss
% function and the model equations) wrt individual variables, and adds
% these equations to the model, together with the corresponding number of
% newly created variables, the Lagrange mutlipliers associated with
% individual equations (see below). Under discretion, `m2`, the
% expectations (leads) are taken as given <?eqtnDiscret?>, and hence the
% terms relating to the expectations are missing from the equations
% compared with commitment, `m3` <?eqtnCommit?>.

eqtn1 = get(m1,'xEqtn');
char(eqtn1)

eqtn2 = get(m2,'xEqtn'); 
char(eqtn2) %?eqtnDiscret?>

eqtn3 = get(m3,'xEqtn'); 
char(eqtn3) %<?eqtnCommit?>

%% Solve Models and Compute Steady State
%
% All the three models are linear (in the case of optimal policy models, a
% linear model with a quadratic loss function always results in a linear
% model). Calculate first their first-order solutions <?solve?> (steady
% state does need to be known in linear models), and then, based on the
% dynamic solution, determine the steady state <?sstate?>. Use the function
% `get` to retrieve a database with the steady-state values <?getSstate?>.
% The steady state values are identical for all three models. In the
% optimal policy models, `m2` and `m3`, the steady-state databases also
% include the newly created Lagrange multipliers, `Mu_Eq1` and `Mu_Eq2`.

m1 = solve(m1); %?solve?
m1 = sstate(m1); %?sstate?
ss1 = get(m1,'sstate') %?getSstate?

m2 = solve(m2); %?solve?
m2 = sstate(m2); %?sstate?
ss2 = get(m2,'sstate') %?getSstate?

m3 = solve(m3); %?solve?
m3 = sstate(m3);  %?sstate?
ss3 = get(m3,'sstate') %?getSstate?

%% Verify Steady State
%
% Verify that the steady state databases are identical for all three
% models, <?verifySstate?>.

maxabs(ss2,ss1) %?verifySstate?
maxabs(ss3,ss2) %?verifySstate?

%% Save Model Objects for Further Use
%
% Save the solved model objects to a mat-file (binary file) for further
% use.

save read_model.mat m1 m2 m3;

%% Help on IRIS Functions Used in This File
%
% Use either `help` to display help in the command window, or `idoc`
% to display help in an HTML browser window.
%
%    help model
%    help model/model
%    help model/get
%    help model/solve
%    help model/sstate
